package com.zz;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.fs.permission.FsPermission;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;

/**
 *  客户端获取常用套路
 *  1、获取一个客户端对象
 *  2、执行相关的操作命令
 *  3、关闭资源
 */
public class HdfsClient {


    private FileSystem fs;

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        // 连接的集群nn地址
        URI uri = new URI("hdfs://hadoop102:8020");
        // 创建配置文件
        Configuration configuration = new Configuration();
        configuration.set("dfs.replication", "2");
        // 用户
        String user = "root";
        // 1. 获取到了一个客户端对象
        fs = FileSystem.get(uri, configuration, user);
    }

    @After
    public void close() throws IOException {
        //3. 关闭资源
        fs.close();
    }


    @Test
    public void tempDir() throws IOException {
        // 2. 创建一个文件夹
        fs.mkdirs(new Path("/xiyou/huaguoshan"));
    }

    /**
     * 参数优先级
     * hdfs-core-site.xml => hdfs-site.xml
     */
    @Test
    public void testPut() throws IOException {
        // 参数解读：参数一：表示删除原数据 参数二：是否允许覆盖 参数三：原数据路径 参数四：目的地路径
        fs.copyFromLocalFile(false, true, new Path("G:\\sunwukong.txt"),
                new Path("/xiyou/huaguoshan"));
    }

    @Test
    public void testGet() throws IOException {
        // 参数解读：参数一：表示删除原数据 参数二：原数据路径 HDFS 参数三：目的地路径 WIN 参数四：是否开启本地文件校验 false 开启
        fs.copyToLocalFile(false,  new Path("/xiyou/huaguoshan"), new Path("G:\\"),
                false);
    }

    @Test
    public void testRm() throws IOException {
        // 参数解读：参数一：删除的路径 参数二： 是否递归删除
        fs.delete(new Path("/xiyou/huaguoshan/sunwukong.txt"),false);

        // 删除非空目录
        fs.delete(new Path("/xiyou/huaguoshan"),true);
    }

    @Test
    public void testMv() throws IOException {
        // 参数解读：参数一：原文件路径 参数二： 目标文件路径

        // 对文件名称修改
//        fs.rename(new Path("/input/word.txt"),new Path("/input/ss.txt"));

        // 移动并更名
//        fs.rename(new Path("/input/ss.txt"),new Path("/cls.txt"));

        // 目录更名
        fs.rename(new Path("/input"), new Path("/output"));
    }

    @Test
    public void testDetail() throws IOException {
        // 获取文件所有信息 第二个参数是否递归
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

        // 遍历文件
        while(listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();

            System.out.println(fileStatus.getPath());
            System.out.println(fileStatus.getPermission());
            System.out.println(fileStatus.getOwner());
            System.out.println(fileStatus.getGroup());
            System.out.println(fileStatus.getLen());
            System.out.println(fileStatus.getModificationTime());
            System.out.println(fileStatus.getReplication());
            System.out.println(fileStatus.getBlockSize());
            System.out.println(fileStatus.getPath().getName());

            // 获取块信息
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println(Arrays.asList(blockLocations));
        }
    }

    @Test
    public void testFile() throws IOException {
        FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : fileStatuses) {
            if(fileStatus.isFile()) {
                System.out.println("文件：" + fileStatus.getPath().getName());
            } else if (fileStatus.isDirectory()) {
                System.out.println("文件夹：" + fileStatus.getPath().getName());
            }
        }
    }

}
